package chapter05

/**
 * Created with IntelliJ IDEA.
 * ClassName: Test05_Lambda
 * Package: chapter05
 * Description:
 * User: fzykd
 *
 * @Author: LQH
 *          Date: 2023-06-22
 *          Time: 14:16
 */

object Test05_Lambda {
  def main(args: Array[String]): Unit = {
    //匿名函数 Lambda表达式
    //(x:Int)=>{函数体} 匿名函数的标准格式就没有返回值
    //(name:String) => {println(name)}

    //1.如何调用匿名函数(name:String)=>{println(name)}
    //2.创建一个变量 把表达式赋值给这个变量 此时变量的类型是一个函数类型 参数是String 返回值Unit
    //此匿名函数的 函数类型 String=>Unit fun就成了这个函数的名称 有了名称就可以正常调用
    val fun = (name: String) => {
      println(name);
    }
    println(fun("匿名函数"))

    //以上使用 还是将匿名函数变相的给了一个名字使用 更多的是将匿名函数作为你一个函数参数使用

    println("-------------------------------")

    //定义一个函数 以函数最为函数参数
    //f函数的参数名是func  func是f函数的参数中函数参数 func这个函数参数的类型是 String=>Unit
    def f(func: String => Unit): Unit = {
      func("这是个啥")
    }

    f(fun)
    //f调用的时候 底层调用的是func这个函数参数类型(String=>Unit)的函数 这个函数是fun
    //那么fun的String的参数就是 func("这是个啥")的参数
    //f(g(x)) 可以这样理解 f函数现在单单值接收数值了 而是要接收操作 这就是实际运用中的用法
    f((name: String) => {
      println(name)
    })

    println("------------------------------------")
    //匿名函数的简化原则
    //1.参数类型可以省略,会根据形成进行自动推导
    f((name) => {
      println(name)
    })
    //2.类型省略后发现只有一个参数 则圆括号可以省略 其他没有参数或者参数超过1的不能省略
    f(name => {
      println(name)
    })
    //3.如果函数体只有一行 花括号也可以省略
    f(name => println(name))
    //4.如果参数只出现一次 则参数省略且后面参数可以使用_代替
    //f(_ => println(_)) 编译器没报错 但是是错误的
    f(println(_))
    //5.如果推断出当前传来的println是一个函数体 而不是调用语句 可以直接省略下划线
    f(println)

    //实际案列
    //定义一个”二元运算“函数 只操作1和2两个数 但是具体运算通过参数
    //表示一个函数类型 (Int,Int)=>Int 参数是两个Int Int 返回值 也是Int
    //以前是传数值 固定加减乘除 现在固定数值 给加减乘除当参数
    def eryuanyunsuan(func: (Int, Int) => Int,a:Int,b:Int): Int = {
      //直接加两个参数 现在 操作方式 和 操作数都不是固定的了
      func(a, b)
    }

    def add(a: Int, b: Int): Int = {
      a + b
    }

    println(eryuanyunsuan(add,1,3))
    println(eryuanyunsuan((a: Int, b: Int) => a + b,1,3))
    //参数的类型是定死了 匿名函数写的时候就可以省略
    println(eryuanyunsuan((a, b) => a + b,1,6))
    //参数只出现一次 使用下划线代替
    println(eryuanyunsuan(_+_,7,8))


  }
}
